package com.zenithmind.common.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.zenithmind.common.security.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Component("myMetaObjectHandler")
@ConditionalOnProperty(name = "zenithmind.mybatis.use-legacy-handler", havingValue = "true", matchIfMissing = false)
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 在插入记录前进行字段填充
     * 该方法主要用于在插入新记录时设置创建时间和更新时间，以及创建者和更新者的标识
     * 如果当前用户已登录，将使用当前用户的ID；否则，将使用默认值"system"
     *
     * @param metaObject 元对象，包含待插入的记录信息
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 记录插入操作开始的日志
        log.info("开始插入填充...");

        // 设置创建时间和更新时间为当前时间
        this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
        // 插入逻辑删除
        this.strictInsertFill(metaObject, "isDeleted", () -> 0, Integer.class);

        try {
            // 尝试获取当前用户的ID
            String userId = SecurityUtils.getCurrentUserId();

            // 如果用户ID不为空，设置创建者和更新者为当前用户
            if (userId != null && !userId.trim().isEmpty()) {
                log.debug("Using userId '{}' for insertFill fields.", userId);
                this.strictInsertFill(metaObject, "createBy", () -> userId, String.class);
                this.strictInsertFill(metaObject, "updateBy", () -> userId, String.class);
            } else {
                log.debug("No userId found in SecurityContext or userId is blank, using default 'system' for insertFill.");
                this.strictInsertFill(metaObject, "createBy", () -> "system", String.class);
                this.strictInsertFill(metaObject, "updateBy", () -> "system", String.class);
            }
        } catch (Exception e) {
            // 如果获取用户ID失败，记录警告日志，并为创建者和更新者提供默认值"system"
            log.warn("获取用户ID失败 (from SecurityContext)，使用默认值 (insertFill)", e);
            this.strictInsertFill(metaObject, "createBy", () -> "system", String.class);
            this.strictInsertFill(metaObject, "updateBy", () -> "system", String.class);
        }
    }

    /**
     * 重写更新填充方法
     * 在更新数据库记录之前，填充公共字段
     *
     * @param metaObject 元对象，包含要更新的实体信息
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        // 记录更新操作的日志
        log.info("开始更新填充...");

        // 设置更新时间字段为当前时间
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);

        try {
            // 尝试获取当前操作用户的ID
            String userId = SecurityUtils.getCurrentUserId();

            // 如果用户ID不为空，设置更新者字段为当前用户ID
            if (userId != null && !userId.trim().isEmpty()) {
                log.debug("Using userId '{}' for updateFill field.", userId);
                this.strictUpdateFill(metaObject, "updateBy", () -> userId, String.class);
            } else {
                log.debug("No userId found in SecurityContext or userId is blank, using default 'system' for updateFill.");
                this.strictUpdateFill(metaObject, "updateBy", () -> "system", String.class);
            }
        } catch (Exception e) {
            // 如果获取用户ID时发生异常，记录警告日志，并将更新者字段设置为默认值"system"
            log.warn("获取用户ID失败 (from SecurityContext)，使用默认值 (updateFill)", e);
            this.strictUpdateFill(metaObject, "updateBy", () -> "system", String.class);
        }
    }
}
